/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.client.ui.aggregate;

import com.sinai.mshab.client.util.Answer;
import com.sinai.mshab.client.ui.FormComponent;

/**
 * This widget consists of 2 other widgets Depending on the answer of widget 1,
 * widget 2 shows up or not. Should widgets1 "show second widget" condition be
 * met, widgets2's answer gets returned else widgets1's answer is returned.
 * 
 * @author serge
 */
public class MultiConditionComponent extends ConditionComponent {

	/**
	 * Create a condition component with the appropriate fields.
	 * 
	 * @param widget1
	 *            the first widget based on which widget2 is showed or not
	 * @param widget2
	 *            the second widget, is not visible until the right condition is
	 *            met.
	 * @param con
	 *            the array of values widget1 could return for widget2 to
	 *            appear.
	 * @param vertical
	 *            specifies whether widget2 should go below (vertical) or to the
	 *            right (not vertical) of widget1.
	 */
	public MultiConditionComponent(FormComponent widget1,
			FormComponent widget2, String con[], boolean vertical) {

		initializeConditionComponent(widget1, widget2, con, vertical);
	}

	/**
	 * Unlike other populate methods, the <code>MultiConditionComponent</code>'s
	 * populate method ignores any parameters provided to it because it does not
	 * follow the assumption of a 1-1 relationship between components and
	 * database tables.
	 * 
	 * @param answer
	 *            the Answer object to ignore.
	 */
	public boolean populate(Answer answer) {
		boolean success_cond = false;
		boolean success_show = false;

		FormComponent conditionWidget = getConditionWidget();
		FormComponent showWidget = getShowWidget();

		boolean same_table_names = conditionWidget.getTableName().equals(
				showWidget.getTableName());

		// population by answer
		if (answer != null) {

			// if same table names, show widget only populated if cond widget cannot be.
			if (same_table_names) {
				success_cond = conditionWidget.populate(answer);
				if (!success_cond) {
					success_show = showWidget.populate(answer);
					
					// if the show widget succesfully populated, show it.
					// and send condition's to the first condition.
					if (success_show) {
						showWidget.setVisible(true);
						condition_met = true;
						conditionWidget.setAnswer(condition[0]);
					}
				}
			}
			// if different table names both widget will be populated.
			else {
				success_cond = conditionWidget.populate(answer);
				success_show = showWidget.populate(answer);
			}
		}
		// population by table name
		else {

			if (same_table_names) {
				success_cond = conditionWidget.populate();
				if (!success_cond) {
					success_show = showWidget.populate();
					
					// if the show widget succesfully populated, show it.
					// and send condition's to the first condition.
					if (success_show) {
						showWidget.setVisible(true);
						condition_met = true;
						conditionWidget.setAnswer(condition[0]);
					}
				}
			}
			// if different table names both widget will be populated.
			else {
				success_cond = conditionWidget.populate();
				success_show = showWidget.populate();
			}
		}

		// if the condition is satisfied after populating, then we should
		// populate the showWidget and display it.
		receiveNotification(conditionWidget, this);
		return success_cond || success_show;
	}

	/**
	 * Unlike other populate methods, the <code>MultiConditionComponent</code>'s
	 * populate method ignores any parameters provided to it because it does not
	 * follow the assumption of a 1-1 relationship between components and
	 * database tables.
	 */
	public boolean populate() {
		return populate(null);
	}

	public Object clone() {
		FormComponent w1new, w2new;
		w1new = (FormComponent) getConditionWidget().clone();
		w2new = (FormComponent) getShowWidget().clone();
		return new MultiConditionComponent(w1new, w2new, getCondition(),
				isVertical());
	}

	public void sendAnswer(DataReceiver receiver) {

		FormComponent condition_widget = getConditionWidget();
		FormComponent show_widget = getShowWidget();

		// if the condition is met and both widgets are visible.
		if (condition_met) {

			// if both widgets come from the same table name, only show widgets
			// answer is sent
			if (condition_widget.getTableName().equals(
					show_widget.getTableName())) {
				show_widget.sendAnswer(receiver);
			}
			// if table names are different, both widgets send their answers.
			else {
				condition_widget.sendAnswer(receiver);
				show_widget.sendAnswer(receiver);
			}
		}
		// if the condition is not met, only the condition widget will send the
		// answer.
		else {
			getConditionWidget().sendAnswer(receiver);
		}
	}
}
